function Contributor(el, anchorId, contributor, contributionType, defaultContributionValue) {
    this.element = jQuery("#"+el);
    this.anchorId = anchorId;

    this.contributor = contributor;
    this.contributionType = contributionType;
    this.defaultContributionValue = defaultContributionValue;

    var _this = this;

    createForm();

    function createForm() {
        var offsetAnchor = findPosition(document.getElementById(_this.anchorId));
        var offsetDiv = findPosition(document.getElementById(el));
        _this.panel = jQuery("<form class='contributor' method='GET'></form>");
        _this.panel.css("top", (offsetAnchor[1] - offsetDiv[1] + 20) + 'px');
        _this.panel.css("left", (offsetAnchor[0] - offsetDiv[0] - 150) + 'px');

        _this.panel.append("<div class='errors' style='color:red;'></div><textarea name='description'></textarea>");
        _this.panel.append("<p><input type='text' class='value' name='value' value='" + _this.defaultContributionValue + "' /></p>");
        _this.panel.append("<input type='hidden' name='contributor' value='" + _this.contributor + "' />");
        _this.panel.append("<input type='hidden' name='type' value='" + _this.contributionType + "' />");

        _this.panel.append("<p class='buttons'><input type='button' value='Добавить' /><input type='button' value='Отменить' /></p>");

        _this.panel.find(".buttons input:first").click(function() {
            jQuery.ajax({
                type:"GET",
                url: "/contributor",
                data: _this.panel.serialize(),
                dataType:"json",
                success: function(text) {                    
                    setErrors(text);

                    if (text.length == 0) {
                        alert('Успешно добавлено ' + _this.panel.find(".value").val() + ' баллов пользователю ' + _this.contributor);
                        _this.panel.addClass("hidden");
                    }
                },
                error: function(xhr) {
                    var status = 0;
                    try {status = xhr.status;} catch(e){};
                    if (status >= 400  && status < 600) _this.panel.html("<span style='color:red;'>Ошибка " + status + "</span>");
                    else _this.panel.html("<span style='color:red;'>Ошибка соединения с сервером</span>");
                }            
            });
        });


        _this.panel.find(".buttons input:last").click(function() {
            _this.panel.addClass("hidden");
        });

        _this.element.html("");
        _this.element.append(_this.panel);
    }

    function setErrors(errors) {
        var div = _this.panel.find(".errors");
        div.html("");

        jQuery(errors).each(function(i) {
            div.append("<div>" + this + "</div>");
        });

        if (errors.length > 0) div.removeClass("hidden");
        else div.addClass("hidden");
    }

    function findPosition(obj) {
        var curtop = 0;
        var curleft = 0;
        if (obj.offsetParent) {
            curleft = obj.offsetLeft;
            curtop = obj.offsetTop;
            while (obj = obj.offsetParent) {
                curleft += obj.offsetLeft;
                curtop += obj.offsetTop;
            }
        }
        return [curleft,curtop];
    }
}
